#include "head.h"

/* Usage:  给客户端发送文件*/
int sendFile(int net_fd, char *path, MYSQL *conn, user_info info){
    //客户端发来命令获得指定文件
    //这里应该写为char *file_name = "传来的指定文件";
    //参数里面加一个存储路径的数组

    //char *file_name = path;
    printf("%s\n", path);
    int flag = 0; //标记文件是否存在，0不存在，1存在
     //3++++++++++++
    //拼接路径
    char *dir = path;
    char *file_name = info.command_str_goto;
    char *client_path = info.path;
    int user_id = atoi(info.username);
    char file_path[1024] = {0};
    memset(file_path, 0, sizeof(file_path));
    strcpy(file_path, client_path);
    strcat(file_path, "/");
    strcat(file_path, file_name);
    printf("file_path = %s\n",file_path);

    sql_t *select = (sql_t *)calloc(1, sizeof(sql_t));
    sprintf(select->query, "select * from file_table where path = '%s' and user_id = %d", file_path, user_id);
    printf("select-query = %s\n", select->query);
    int res = mysql_query(conn, select->query);
    MYSQL_ERROR_CHECK(conn, res, 1);
    //printf("过\n");

    select->result = mysql_store_result(conn);
    if (select->result == NULL) {
        fprintf(stderr, "mysql_store_result() failed\n");
        //mysql_close(conn);
        flag = 0;
        send(net_fd, &flag, sizeof(flag), MSG_NOSIGNAL);
        return 0;
    }

    // 获取结果行
    select->row = mysql_fetch_row(select->result);
    if (select->row == NULL) {
        fprintf(stderr, "没有获取到任何行\n");
        mysql_free_result(select->result);
        //mysql_close(conn);
        flag = 0;
        send(net_fd, &flag, sizeof(flag), MSG_NOSIGNAL);
        return 0;
    }

    printf("select->row[6] = %s\n", select->row[6]);

    char hash[1024] = {0};
    memset(hash, 0, sizeof(hash));
    if (select->row[6] != NULL) {
        strncpy(hash, select->row[6], sizeof(hash) - 1);
    }

    printf("hash = %s\n", hash);

    free(select);                          

    printf("1\n");
    //3++++++++++++
    //这里是客户端文件夹在服务器的绝对路径

    //拼接路径
    //char *dir = path;


    DIR *dirp = opendir(dir);
    ERROR_CHECK(dirp, NULL, "opendir");

    struct dirent *pdirent;
    //遍历客户端文件下的文件
    while((pdirent = readdir(dirp)) != NULL){
        //找到文件，结束循环，继续往下走
        if(strcmp(hash, pdirent->d_name) == 0){
            //printf("存在%s文件\n", file_name);
            flag = 1;
            send(net_fd, &flag, sizeof(flag), MSG_NOSIGNAL);
            break;
        }
    }
    //readdir会自动移向下一个文件/文件夹
    //找到文件，将目录倒带，回到目录中的第一个条目
    rewinddir(dirp);

    closedir(dirp);
    if(flag == 0){
        //没有对应文件，结束
        //printf("没有该文件\n");
        //发送标记位flag=0，表示文件不存在    
        send(net_fd, &flag, sizeof(flag), MSG_NOSIGNAL);

        return 0;
    }
    // 打开文件
    //拼接文件
    char server_path[1024] = {0};
    memset(server_path, 0, sizeof(server_path));
    strcpy(server_path, path);
    strcat(server_path, hash);
    printf("server_path = %s\n", server_path);

    int file_fd = open(server_path, O_RDWR);

    struct stat st;
    memset(&st, 0, sizeof(st));
    fstat(file_fd, &st);

    //发送文件大小
    off_t file_size = st.st_size;
    //MSG_NOSIGNA使服务端不抛出sigpipe信号
    send(net_fd, &file_size, sizeof(off_t), MSG_NOSIGNAL);
    printf("file_size = %ld\n", file_size);
    //发送文件名长度和文件名
    int name_len = strlen(file_name);
    send(net_fd, &name_len, sizeof(int), MSG_NOSIGNAL);
    send(net_fd, file_name, name_len, MSG_NOSIGNAL);
    printf("%d\n", name_len);

    //接收已传文件大小
    off_t off_reset = 0;
    int offset_recv = recv(net_fd, &off_reset, sizeof(off_reset), MSG_NOSIGNAL);
    ERROR_CHECK(offset_recv, -1, "recv");
    
    //计算偏移量
    off_t off_set = off_reset / 4096 * 4096;                                                                       
    printf("off_set = %ld\n", off_set);
    //mmap映射磁盘文件
    if(off_reset < file_size){

        //还要传输的文件大小
        off_t re_offset = file_size - off_set;
        printf("re_offset = %ld\n", re_offset);

        void *p = mmap(NULL, re_offset, PROT_READ|PROT_WRITE, MAP_SHARED, file_fd, off_set);


        printf("st_size: %ld\n", st.st_size);
        int res_send = send(net_fd, p, re_offset, MSG_NOSIGNAL);
        ERROR_CHECK(res_send, -1, "res_send");
        //printf("传输完\n");
        munmap(p, st.st_size);


        close(file_fd);

        return 0;

    }else{
        //printf("已有最新的文件\n");
        close(file_fd);
        return 0;
    }

}
